const express = require('express')
const router = express.Router()
const fs = require('fs')
const path = require('path')
const db = require('../utils/database')
const { authenticate } = require('../middleware/auth')
const {
  scanDictionary,
  scanWordPronunciations,
  getWordDetails,
  getCoursePath,
  getLessonContent,
  findBaseWord,
  findWordVariants,
  getWordPronunciation,
  getPhonetic
} = require('../utils/resourceScanner')
const logger = require('../utils/logger')

// Get difficult words for a specific lesson
router.get('/difficult-words/:courseId/:lessonId', authenticate, async (req, res) => {
  try {
    const { courseId, lessonId } = req.params
    const userId = req.user.id

    // Get the course path from the course ID
    const coursePath = getCoursePath(courseId)
    if (!coursePath) {
      return res.status(404).json({ message: 'Course not found' })
    }

    // Get the lesson content
    const lessonContent = await getLessonContent(coursePath, lessonId)
    if (!lessonContent || lessonContent.length === 0) {
      return res.status(404).json({ message: 'Lesson not found' })
    }

    // Extract all words from the lesson content
    const allWords = new Set()
    lessonContent.forEach((sentence) => {
      if (sentence.english) {
        // Extract words from the English sentence
        const words = sentence.english
          .toLowerCase()
          .replace(/[^\w\s]/g, '') // Remove punctuation
          .split(/\s+/) // Split by whitespace
          .filter((word) => word.length > 0) // Remove empty strings

        words.forEach((word) => allWords.add(word))
      }
    })

    // If no words found, return empty array
    if (allWords.size === 0) {
      return res.json([])
    }

    // Query difficult words (user vocabulary) that match the words in this lesson
    let wordArray = Array.from(allWords)
    const variantsArr = []
    for (let i = 0; i < wordArray.length; i++) {
      let variants = await findWordVariants(wordArray[i])
      let baseWord = await findBaseWord(wordArray[i])
      variants.indexOf(baseWord) === -1 && variants.push(baseWord)
      for (const variant of variants) {
        wordArray.indexOf(variant) === -1 && variantsArr.indexOf(variant) && variantsArr.push(variant)
      }
    }
    wordArray = wordArray.concat(variantsArr)
    const placeholders = wordArray.map(() => '?').join(',')
    const query = `
      SELECT vocabulary, is_learned, is_favorite, times_encountered, times_practiced, 
             last_encountered_at, created_at, updated_at
      FROM user_vocabulary 
      WHERE user_id = ? AND vocabulary IN (${placeholders})
      AND is_learned = 0
      ORDER BY last_encountered_at DESC
    `

    db.all(query, [userId, ...wordArray], async (err, rows) => {
      if (err) {
        return res.status(500).json({
          message: 'Error fetching difficult words',
          error: err.message
        })
      }

      // 遍历rows,将单词的变体也加入到rows
      // 变体查找单词原型的方式为：findBaseWord(word);
      // 参考findBaseWord实现
      // TODO:
      const additionalWords = []
      for (const row of rows) {
        // 通过原型查找变体
        const variants = await findWordVariants(row.vocabulary)
        for (const variant of variants) {
          // 检查变体是否已经在结果中
          const exists =
            rows.some((r) => r.vocabulary === variant) || additionalWords.some((w) => w.vocabulary === variant)

          if (!exists) {
            // 直接使用原型的其他信息赋值给变体
            const variantRow = {
              vocabulary: variant,
              is_learned: row.is_learned,
              is_favorite: row.is_favorite,
              times_encountered: row.times_encountered,
              times_practiced: row.times_practiced,
              last_encountered_at: row.last_encountered_at,
              created_at: row.created_at,
              updated_at: row.updated_at
            }

            additionalWords.push(variantRow)
          }
        }
      }

      // 合并原始结果和变体单词
      const combinedRows = [...rows, ...additionalWords]

      res.json(combinedRows)
    })
  } catch (error) {
    console.error('Error fetching difficult words for lesson:', error)
    res.status(500).json({
      message: 'Error fetching difficult words for lesson',
      error: error.message
    })
  }
})
router.get('/phonetic/:word', async (req, res) => {
  const { word } = req.params
  try {
    const result = {
      word: word,
      phonetic: await getPhonetic(word)
    }
    res.json(result)
  } catch (error) {
    logger.error('Error fetching phonetic for word:', error)
    res.status(500).json({
      message: 'Error fetching phonetic for word',
      error: error.message
    })
  }
})
// Get IELTS words for a specific lesson
router.get('/ielts/:courseId/:lessonId', async (req, res) => {
  try {
    const { courseId, lessonId } = req.params

    // Get the course path from the course ID
    const coursePath = getCoursePath(courseId)
    if (!coursePath) {
      return res.status(404).json({ message: 'Course not found' })
    }

    // Get the lesson content
    const lessonContent = await getLessonContent(coursePath, lessonId)
    if (!lessonContent || lessonContent.length === 0) {
      return res.status(404).json({ message: 'Lesson not found' })
    }

    // Extract all words from the lesson content
    const allWords = new Set()
    lessonContent.forEach((sentence) => {
      if (sentence.english) {
        // Extract words from the English sentence
        const words = sentence.english
          .toLowerCase()
          .replace(/[^\w\s]/g, '') // Remove punctuation
          .split(/\s+/) // Split by whitespace
          .filter((word) => word.length > 0) // Remove empty strings

        words.forEach((word) => allWords.add(word))
      }
    })

    // If no words found, return empty array
    if (allWords.size === 0) {
      return res.json([])
    }

    // Query IELTS words that match the words in this lesson
    const wordArray = Array.from(allWords)
    const placeholders = wordArray.map(() => '?').join(',')
    const query = `
      SELECT word 
      FROM ielst_words 
      WHERE word IN (${placeholders})
      ORDER BY word
    `

    db.all(query, wordArray, (err, rows) => {
      if (err) {
        return res.status(500).json({ message: 'Error fetching IELTS words', error: err.message })
      }

      const ieltsWords = rows.map((row) => row.word)
      res.json(ieltsWords)
    })
  } catch (error) {
    console.error('Error fetching IELTS words for lesson:', error)
    res.status(500).json({
      message: 'Error fetching IELTS words for lesson',
      error: error.message
    })
  }
})

// Get dictionary entries
router.get('/dictionary', async (req, res) => {
  try {
    const dictionary = await scanDictionary()
    res.json(dictionary)
  } catch (error) {
    res.status(500).json({ message: 'Error fetching dictionary', error: error.message })
  }
})

// Get word pronunciations
router.get('/pronunciations', async (req, res) => {
  try {
    const pronunciations = await scanWordPronunciations()
    res.json(pronunciations)
  } catch (error) {
    res.status(500).json({ message: 'Error fetching pronunciations', error: error.message })
  }
})

// Get word details
router.get('/word/:word', async (req, res) => {
  try {
    const { word } = req.params
    const wordDetails = await getWordDetails(word)
    if (!wordDetails) {
      return res.json({ message: '没有找到该单词，请检查拼写！' })
    }
    const pronunciation = await getWordPronunciation(word)
    if (wordDetails) {
      wordDetails.pronunciation = pronunciation
      res.json(wordDetails)
    }
  } catch (error) {
    if (error.message === 'Word not found') {
      // 尝试查找词形变化
      res.status(404).json({ message: 'Word not found', error: error.message })
    } else {
      res.status(500).json({ message: 'Error fetching word details', error: error.message })
    }
  }
})

// Get pronunciation audio for a specific word
router.get('/pronunciation/:word', async (req, res) => {
  try {
    const { word } = req.params
    const wordFirstLetter = word.charAt(0).toLowerCase()
    const wordPronDir = path.join(__dirname, '../../resources/word-pronunciation')

    // 构建文件路径（尝试不同的文件扩展名）
    const extension = '.mp3'
    const filePath = path.join(wordPronDir, wordFirstLetter, `${word}${extension}`)

    if (!fs.existsSync(filePath)) {
      // 尝试查找词形变化
      try {
        const baseWord = await findBaseWord(word)
        if (baseWord && baseWord !== word) {
          const baseWordFirstLetter = baseWord.charAt(0).toLowerCase()
          const baseWordFilePath = path.join(wordPronDir, baseWordFirstLetter, `${baseWord}${extension}`)

          if (fs.existsSync(baseWordFilePath)) {
            // 读取音频文件并返回base64编码
            const audioBuffer = fs.readFileSync(baseWordFilePath)
            const audioBase64 = audioBuffer.toString('base64')
            return res.send(audioBase64)
          }
        }
      } catch (baseWordError) {
        // 忽略查找基本词时的错误
      }

      return res.status(404).json({ message: 'Pronunciation not found' })
    }

    // 读取音频文件并返回base64编码
    const audioBuffer = fs.readFileSync(filePath)
    const audioBase64 = audioBuffer.toString('base64')
    res.send(audioBase64)
  } catch (error) {
    console.error('Error fetching pronunciation:', error)
    res.status(500).json({ message: 'Error fetching pronunciation', error: error.message })
  }
})

// 更新或创建用户词汇状态
router.post('/user', authenticate, (req, res) => {
  const userId = req.user.id
  const { word, is_learned, is_favorite, times_encountered, times_practiced } = req.body

  // 验证word参数是否存在
  if (!word) {
    return res.status(400).json({ message: 'Word is required' })
  }

  const query = `
    INSERT INTO user_vocabulary (user_id, vocabulary, is_learned, is_favorite, times_encountered, times_practiced)
    VALUES (?, ?, ?, ?, ?, ?)
    ON CONFLICT(user_id, vocabulary) 
    DO UPDATE SET 
      is_learned = excluded.is_learned,
      is_favorite = excluded.is_favorite,
      times_encountered = excluded.times_encountered,
      times_practiced = excluded.times_practiced,
      last_encountered_at = CURRENT_TIMESTAMP,
      updated_at = CURRENT_TIMESTAMP
  `

  db.run(
    query,
    [userId, word, is_learned ? 1 : 0, is_favorite ? 1 : 0, times_encountered || 1, times_practiced || 0],
    function (err) {
      if (err) {
        return res.status(500).json({
          message: 'Error updating user vocabulary',
          error: err.message
        })
      }
      res.json({
        id: this.lastID,
        message: 'User vocabulary updated successfully'
      })
    }
  )
})

// 获取用户生词本中的单词详情（包括发音和注释）
router.get('/user/:word', authenticate, async (req, res) => {
  try {
    const { word } = req.params
    const userId = req.user.id

    // 获取单词详情（发音、注释等）
    const wordDetails = await getWordDetails(word)

    // 获取用户对该单词的学习状态
    const userVocabQuery = `
      SELECT is_learned, is_favorite, times_encountered, times_practiced, last_encountered_at
      FROM user_vocabulary 
      WHERE user_id = ? AND vocabulary = ?
    `

    db.get(userVocabQuery, [userId, word], async (err, row) => {
      if (err) {
        return res.status(500).json({
          message: 'Error fetching user vocabulary',
          error: err.message
        })
      }

      // 获取发音
      const pronunciation = await getWordPronunciation(word)

      let everMarked = false
      if (!row) everMarked = false
      if (row && row.is_learned === 0) {
        everMarked = true
      }

      // 合并单词详情和用户学习状态
      const result = {
        ...(wordDetails || { word }),
        pronunciation,
        userProgress: row || null,
        everMarked
      }

      res.json(result)
    })
  } catch (error) {
    console.error('Error fetching word details:', error)
    res.status(500).json({
      message: 'Error fetching word details',
      error: error.message
    })
  }
})

// 获取用户词汇列表（分页）
router.get('/user', authenticate, async (req, res) => {
  const userId = req.user.id
  const page = parseInt(req.query.page) || 1
  const limit = parseInt(req.query.limit) || 20
  const filter = req.query.filter // 可选: learned, favorite
  const offset = (page - 1) * limit

  let query = `
    SELECT vocabulary, is_learned, is_favorite, times_encountered, times_practiced, 
           last_encountered_at, created_at as user_vocab_created_at, updated_at as user_vocab_updated_at
    FROM user_vocabulary
    WHERE user_id = ? AND is_learned = 0
  `

  const countQuery = `
    SELECT COUNT(*) as total
    FROM user_vocabulary
    WHERE user_id = ? AND is_learned = 0
  `

  const params = [userId]
  const countParams = [userId]

  if (filter === 'favorite') {
    query += ' AND is_favorite = 1'
    countQuery += ' AND is_favorite = 1'
  }

  query += ' ORDER BY last_encountered_at DESC LIMIT ? OFFSET ?'
  params.push(limit, offset)

  db.get(countQuery, countParams, async (err, countResult) => {
    if (err) {
      return res.status(500).json({ message: 'Error counting vocabulary', error: err.message })
    }

    const total = countResult.total

    db.all(query, params, async (err, rows) => {
      if (err) {
        return res.status(500).json({ message: 'Error fetching user vocabulary', error: err.message })
      }

      // 为每个词汇获取详细信息（音标、翻译等）
      const vocabularyWithDetails = []
      for (const row of rows) {
        try {
          const wordDetails = await getWordDetails(row.vocabulary)
          // 获取发音
          const pronunciation = await getWordPronunciation(row.vocabulary)

          vocabularyWithDetails.push({
            ...row,
            ...(wordDetails || { word: row.vocabulary }),
            pronunciation
          })
        } catch (detailErr) {
          // 如果获取详细信息失败，仍然保留基本的词汇信息
          vocabularyWithDetails.push({
            ...row,
            word: row.vocabulary
          })
        }
      }

      res.json({
        vocabulary: vocabularyWithDetails,
        total,
        page,
        limit
      })
    })
  })
})

module.exports = router
